#include		<iostream>
#include		"../parser/RequestParser.hpp"
#include	 	"traitThread.hpp"
#include		"../requests/Request.h"
#ifndef _WIN32
 #include		"../Network/ZiaServerUnix/ZiaServerUnix.h"
#else
 #include		"../Network/ZiaServerWin/ZiaServerWin.h"
#endif
#include		"../Api Headers/DataTree.hpp"
#include		"../CrossThread/ManipList.hpp"
#include		"../requests/Request.h"
#include		"../tools/tools.hpp"
#include		"../Api Headers/HttpStep.hpp"
#include		"../IMessage/Message.hpp"
#include		"../Network/Connection.hpp"
#include		"../XmlParser/XmlParser.hpp"
#include		<utility>
#include		<fstream>

using namespace	std;
zia::api::DataTree			confEnv;
extern ManipList<pair<std::string, int> >		msgList;

void							doStepActions(zia::api::HttpStepID id,  zia::Message *msg)
{
  id = id;
  msg = NULL;

	return ;
}
void							parserSteps(const std::string &request, zia::Message *msg)
{
	RequestParser	Parser;

	doStepActions(zia::api::STEP_PARSER_PRE, msg);
	Parser.ParseRequest(request, msg->http(), msg->_body);
	msg->http()["body"] = msg->_body;
	doStepActions(zia::api::STEP_PARSER_POST, msg);
	return ;
}


void							ExecSteps(zia::Message *msg)
{
	Request						traitRequest;
		
	doStepActions(zia::api::STEP_EXEC_PRE, msg);
	if (msg->http()["Method"] == "GET" || msg->http()["Method"] == "POST")
		msg->_body = traitRequest.traitGET(msg->http()["URL"], msg->httpResp());
	else if (msg->http()["Method"] == "HEAD")
		traitRequest.traitHEAD(msg->http()["URL"], msg->httpResp());
	else if (msg->http()["Method"] == "DELETE")
		traitRequest.traitDELETE(msg->http()["URL"]);
	else if (msg->http()["Method"] == "PUT")
		traitRequest.traitPOST(msg->http()["body"]);
		//	else if (msg->http()["Method"] == "POST")
//		msg->_body = traitRequest.traitGET(msg->http()["URL"], msg->httpResp());

	doStepActions(zia::api::STEP_EXEC_POST, msg);
	return ;
}

void							RawerSteps(zia::Message *msg)
{
	std::string	body;

		doStepActions(zia::api::STEP_RAWER_PRE, msg);
		body = msg->_body;
		msg->_body = msg->http()["version"];
		msg->_body += " ";
		msg->_body += msg->http()["code"];
		msg->_body += " ";
		msg->_body += msg->http()["msg"];
		msg->_body += "\r\n";
		//Date
//		msg->_body += "Date : ";
//		msg->_body += msg->http()["date"];
//		msg->_body += "\r\n";
		//ServerType
		msg->_body += "Server : ";
		msg->_body += msg->http()["server"];
		msg->_body += "\r\n";
		//Contenu
		if (msg->http()["type"] != "")
		msg->_body += "Content-Type : ";
		msg->_body += msg->http()["type"];
		msg->_body += "\r\n";
		//Taille
		msg->_body += "Content-Length : ";
		msg->_body += msg->http()["length"];
		msg->_body += "\r\n";
		msg->_body += "\r\n";

		msg->_body += body;
		doStepActions(zia::api::STEP_RAWER_POST, msg);
}

void							*TraitLoop(void *useless)
{
	XmlParser					confParser;
	void						*troll;
	const pair<string, int>		*msg = NULL;

	confParser.setFile("conf.xml");
	cout << "Thread Launched" << endl;
	troll = useless;
	while (1)
	{
		msg = msgList.takeMessage();
		if (msg != NULL)
		{
			confParser.parseFile();
			zia::Connection			connection;
			zia::Message			currentRequest(connection);

			RequestParser			Parser;

			parserSteps(msg->first, &currentRequest);
			ExecSteps(&currentRequest);
			RawerSteps(&currentRequest);
			send(msg->second, currentRequest._body.c_str(), currentRequest._body.size(), 0);
//			std::cout << " ============ Sent ============ " << std::endl;
//			std::cout << currentRequest._body << std::endl;
//			std::cout << " ================================ " << std::endl;

			#ifndef _WIN32
				close(msg->second);
			#else
				closesocket(msg->second);
			#endif
			std::cout << "Closed" << std::endl;
			delete msg;
		}
		::tools::Sleep(1);
	}
	return (NULL);
}
